﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Fly.Common.Extensions
{
    /// <summary>
    /// 数据转换辅助类
    /// </summary>
    public static class ConvertExtensions
    {
        #region 尝试转换指定字符串为指定的值类型，如果转换出错则返回默认值。
        /// <summary>
        /// 尝试转换指定字符串为指定的值类型，如果转换出错则返回默认值。
        /// </summary>
        /// <typeparam name="T">指定的目标类型</typeparam>
        /// <param name="str">需要转换的字符串</param>
        /// <param name="defValue">转换失败时的默认值</param>
        /// <returns></returns>
        public static T TryParse<T>(this string str, T defValue) where T : struct
        {
            var t = typeof(T);

            #region 执行转换操作

            if (t == typeof(int))
            {
                #region Int32 类型

                int reslut;
                if (int.TryParse(str, out reslut))
                {
                    return (T)Convert.ChangeType(str, typeof(int));
                }

                #endregion
            }
            else if (t == typeof(double))
            {
                #region double

                double reslut;
                if (double.TryParse(str, out reslut))
                {
                    return (T)Convert.ChangeType(str, t);
                }

                #endregion
            }
            else if (t == typeof(decimal))
            {
                #region decimal

                decimal reslut;
                if (decimal.TryParse(str, out reslut))
                {
                    return (T)Convert.ChangeType(str, t);
                }

                #endregion

            }
            else if (t == typeof(float))
            {
                #region float

                float reslut;
                if (float.TryParse(str, out reslut))
                {
                    return (T)Convert.ChangeType(str, t);
                }

                #endregion
            }
            else if (t == typeof(sbyte))
            {
                #region sbyte

                sbyte reslut;
                if (sbyte.TryParse(str, out reslut))
                {
                    return (T)Convert.ChangeType(str, t);
                }

                #endregion
            }
            else if (t == typeof(byte))
            {
                #region byte

                byte reslut;
                if (byte.TryParse(str, out reslut))
                {
                    return (T)Convert.ChangeType(str, t);
                }

                #endregion
            }
            else if (t == typeof(short))
            {
                #region short

                short reslut;
                if (short.TryParse(str, out reslut))
                {
                    return (T)Convert.ChangeType(str, t);
                }

                #endregion
            }
            else if (t == typeof(Single))
            {
                #region Single

                Single reslut;
                if (Single.TryParse(str, out reslut))
                {
                    return (T)Convert.ChangeType(str, t);
                }

                #endregion
            }
            else if (t == typeof(Int64))
            {
                #region Int64

                Int64 reslut;
                if (Int64.TryParse(str, out reslut))
                {
                    return (T)Convert.ChangeType(str, t);
                }

                #endregion
            }
            else if (t == typeof(UInt32))
            {
                #region UInt32

                UInt32 reslut;
                if (UInt32.TryParse(str, out reslut))
                {
                    return (T)Convert.ChangeType(str, t);
                }

                #endregion
            }
            else if (t == typeof(UInt64))
            {
                #region UInt64

                UInt64 reslut;
                if (UInt64.TryParse(str, out reslut))
                {
                    return (T)Convert.ChangeType(str, t);
                }

                #endregion
            }
            else if (t == typeof(Int16))
            {
                #region Int16

                Int16 result;
                if (Int16.TryParse(str, out result))
                {
                    return (T)Convert.ChangeType(str, t);
                }

                #endregion
            }
            else if (t == typeof(UInt16))
            {
                #region UInt16

                UInt16 result;
                if (UInt16.TryParse(str, out result))
                {
                    return (T)Convert.ChangeType(str, t);
                }

                #endregion
            }
            else if (t == typeof(Char))
            {
                #region Char

                Char result;
                if (Char.TryParse(str, out result))
                {
                    return (T)Convert.ChangeType(str, t);
                }

                #endregion
            }
            else if (t == typeof(bool))
            {
                #region bool

                bool result;
                if (str.Equals("true", StringComparison.OrdinalIgnoreCase))
                {
                    return (T)Convert.ChangeType("1", t);
                }
                if (str.Equals("false", StringComparison.OrdinalIgnoreCase))
                {
                    return (T)Convert.ChangeType("0", t);
                }
                if (bool.TryParse(str, out result))
                {
                    return (T)Convert.ChangeType(str, t);
                }

                #endregion

            }
            else if (t == typeof(Guid))
            {
                #region Guid
                Guid guid;
                if (Guid.TryParse(str, out guid))
                {
                    return (T)Convert.ChangeType(Guid.Parse(str), t);
                } 
                #endregion
            }
            else if (t == typeof (Enum))
            {
                #region Enum
                T value;
                if (Enum.TryParse(str, out value))
                {
                    return value;
                } 
                #endregion
            }

            #endregion
            
            return defValue;
        }

        #endregion
    }
}
